/*
 * \brief  Single connected list
 * \author Norman Feske
 * \date   2006-08-02
 */

/*
 * Copyright (C) 2006-2009 Norman Feske
 * Genode Labs, Feske & Helmuth Systementwicklung GbR
 *
 * This file is part of the Genode OS framework, which is distributed
 * under the terms of the GNU General Public License version 2.
 */

#ifndef _INCLUDE__UTIL__LIST_H_
#define _INCLUDE__UTIL__LIST_H_

namespace Genode {

	/*
	 * \param LT  list element type
	 */
	template <typename LT>
	class List
	{
		private:

			LT *_first;

		public:

			class Element
			{
				protected:

					friend class List;

					LT *_next;

				public:

					Element(): _next(0) { }

					/**
					 * Return next element in list
					 */
					LT *next() { return _next; }
			};

		public:

			/**
			 * Constructor
			 *
			 * Start with an empty list.
			 */
			List(): _first(0) { }

			/**
			 * Return first list element
			 */
			LT *first() { return _first; }

			/**
			 * Insert element into list
			 */
			void insert(LT *le)
			{
				le->Element::_next = _first;
				_first = le;
			}

			/**
			 * Remove element from list
			 */
			void remove(LT *le)
			{
				if (!_first) return;

				/* if specified element is the first of the list */
				if (le == _first)
					_first = le->Element::_next;

				else {

					/* search specified element in the list */
					Element *e = _first;
					while (e->_next && (e->_next != le))
						e = e->_next;

					/* element is not member of the list */
					if (!e->_next) return;

					/* e->_next is the element to remove, skip it in list */
					e->Element::_next = e->Element::_next->Element::_next;
				}

				le->Element::_next = 0;
			}
	};
}

#endif /* _INCLUDE__UTIL__LIST_H_ */
